#include "EPubPagingImp.h"
#include "EPubPageImp.h"

EPubPointer<IEPubPage> EPubPagingImp::GetFirstPage() const
{
	EPubPageList::const_iterator pos = m_PageList.begin();
	if(pos == m_PageList.end()) {
		return NULL;
	}
	return (*pos).Cast<IEPubPage>();
}

EPubPointer<IEPubPage> EPubPagingImp::GetLastPage() const
{
	if(m_PageList.size() == 0) {
		return NULL;
	}

	return (*(--m_PageList.end())).Cast<IEPubPage>();
}

EPubPointer<IEPubPage> EPubPagingImp::AddPage(EPubPointer<IEPubMedia> mediaFile)
{
	EPubPointer<EPubPageImp> page_prev = GetLastPage().As<EPubPageImp>();
	EPubPointer<EPubPageImp> cur(new EPubPageImp(mediaFile, m_PageList.size(), page_prev.Get()));
	m_PageList.push_back(cur);
	if(page_prev) { page_prev->m_NextPage = cur.Get(); }
	return cur.Cast<IEPubPage>();
}

EPubPointer<IEPubPage> EPubPagingImp::InsertPage(EPubPointer<IEPubMedia> mediaFile, EPUB_UInt32 index)
{
	if(index > m_PageList.size()) {
		return NULL;
	}

	if(index == m_PageList.size()) {
		return AddPage(mediaFile);
	}

	for(EPubPageList::iterator iter = m_PageList.begin();
		iter != m_PageList.end();
		++iter)
	{
		if((*iter)->GetPageIndex() == index) {
			EPubPointer<EPubPageImp> page_next = (*iter).As<EPubPageImp>();
			EPubPointer<EPubPageImp> page_prev = page_next->GetPrevPage().As<EPubPageImp>();
			EPubPointer<EPubPageImp> cur(new EPubPageImp(mediaFile, index, page_prev.Get(), page_next.Get()));

			if(page_next) { page_next->m_PrevPage = cur.Get(); }
			if(page_prev) { page_prev->m_NextPage = cur.Get(); }

			for(EPubPageList::iterator iter_back = iter;
				iter_back != m_PageList.end();
				++iter_back)
			{
				EPubPointer<EPubPageImp> temp = (*iter_back).As<EPubPageImp>();
				temp->m_PageIndex++;
			}

			m_PageList.insert(iter, cur);
			return cur.Cast<IEPubPage>();
		}
	}

	return NULL;
}

EPUB_Result EPubPagingImp::RemovePage(EPUB_UInt32 index)
{
	EPUB_Result ret = EPUB_SUCCESS;

	if(m_PageList.empty()) {
		return -1;
	}

	if(index > m_PageList.size()) {
		return -1;
	}

	for(EPubPageList::iterator iter = m_PageList.begin();
		iter != m_PageList.end();
		++iter)
	{
		if((*iter)->GetPageIndex() == index) {
			EPubPointer<EPubPageImp> cur = (*iter).As<EPubPageImp>();
			EPubPageImp * page_prev = dynamic_cast<EPubPageImp *>(cur->m_PrevPage);
			EPubPageImp * page_next = dynamic_cast<EPubPageImp *>(cur->m_NextPage);

			if(page_prev) { page_prev->m_NextPage = page_next; }
			if(page_next) { page_next->m_PrevPage = page_prev; }

			for(EPubPageList::iterator iter_back = iter;
				iter_back != m_PageList.end();
				++iter_back)
			{
				EPubPointer<EPubPageImp> temp = (*iter_back).As<EPubPageImp>();
				temp->m_PageIndex--;
			}

			m_PageList.erase(iter);
			return ret;
		}
	}

	return -1;
}